/*

Copyright (C) 2007 Thomas Geiger (tom.geiger@gmail.com)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

*/

#include "OGSADAIConnection.h"

OGSADAIConnection* OGSADAIConnection::instance = NULL;

OGSADAIConnection* OGSADAIConnection::GetConnection() {

	if (instance == NULL) {
		instance = new OGSADAIConnection();
	}
	return instance;
}

OGSADAIConnection::OGSADAIConnection() {
	
 	options[0].optionString = "-Djava.class.path=.:lib/activation.jar:lib/addressing-1.0.jar:lib/axis.jar:\
lib/cog-axis.jar:lib/cog-jglobus.jar:lib/cog-url.jar:\
lib/commons-discovery.jar:lib/commons-logging.jar:lib/cryptix32.jar:lib/cryptix-asn1.jar:\
lib/cryptix.jar:lib/hsqldb.jar:lib/jakarta-oro-2.0.8.jar:lib/jaxrpc.jar:lib/jce-jdk13-125.jar:\
lib/log4j-1.2.8.jar:lib/lucene-1.4.3.jar:lib/mail.jar:lib/ogsadai-activities.jar:\
lib/ogsadai-core.jar:lib/ogsadai-examples.jar:lib/ogsadai-tools.jar:lib/ogsadai-wsrf.jar:\
lib/ogsadai-wsrf-stubs.jar:lib/opensaml.jar:lib/puretls.jar:lib/saaj.jar:lib/servlet.jar:\
lib/wsdl4j.jar:lib/wsrf_common.jar:lib/wsrf_core.jar:lib/wsrf_core_stubs.jar:\
lib/wsrf_provider_jce.jar:lib/wsrf_tools.jar:lib/wss4j.jar:lib/xalan.jar:lib/xercesImpl.jar:\
lib/xml-apis.jar:lib/xmldb.jar:lib/xmlsec.jar";
 	
 	//options[1].optionString = "-verbose:jni";
 	memset(&vm_args, 0, sizeof(vm_args));
 	vm_args.version = JNI_VERSION_1_2;
 	vm_args.nOptions = 1;
 	vm_args.options = options;
 	
 	status = JNI_ERR;
 	status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
 	
 	//cerr << "JVM status: " << status << endl;
 	
 	// XXX check for return value
 	
 	cls = env->FindClass( "OGSADAIClient" );
 	
 	//XXX: check for cls
 	
 	obj = env->AllocObject(cls);
 	
 	// XXX: check for obj
 	
 	isconnected = false;
}

OGSADAIConnection::~OGSADAIConnection() {
	jvm->DestroyJavaVM();
}


bool OGSADAIConnection::open(const string& url, const string& auth) {
	
	mid = env->GetMethodID(cls, "connect", "(Ljava/lang/String;Ljava/lang/String;)Z"); 
	if (mid != 0) {

		// build arg strings
		jstring arg0 = env->NewStringUTF(url.c_str());
		jstring arg1 = env->NewStringUTF(auth.c_str());
		
		// call method
		jboolean result = env->CallBooleanMethod(obj, mid, arg0, arg1);
		
		env->DeleteLocalRef(arg0);
		env->DeleteLocalRef(arg1);
		
		if (result) {
			isconnected = true;
		}
		
		return result;
	}
	cerr << "Error calling method 'open'" << endl;
	return false;
}

bool OGSADAIConnection::close() {
	
	mid = env->GetMethodID(cls, "close", "()Z"); 
	if (mid != 0) {
		// call method
		jboolean result = env->CallBooleanMethod(obj, mid);
		
		if (result) {
			isconnected = false;
		}
		
		return result;
	}
	cerr << "Error calling method 'close'" << endl;
	return false;
}

bool OGSADAIConnection::isConnected() {
	return isconnected;
}

string OGSADAIConnection::executeQuery(const string& sql) {
	
	mid = env->GetMethodID(cls, "executeQuery", "(Ljava/lang/String;)Ljava/lang/String;"); 
	if (mid != 0) {
		// build arg string
		jstring arg = env->NewStringUTF(sql.c_str());
				
		// call method
		jstring result = (jstring) env->CallObjectMethod(obj, mid, arg);	
				 	
		// convert result
		const char* cstr = env->GetStringUTFChars(result, 0);
			
		// copy result to c++ string
		string res = string(cstr);
				
		// cleanup
		env->ReleaseStringUTFChars(result, cstr); 
		env->DeleteLocalRef(result);
		env->DeleteLocalRef(arg);
				
		// return result
		return res;	
	}
	cerr << "Error calling method 'executeQuery'" << endl;
	return false;
}

string OGSADAIConnection::executeUpdate(const string& sql) {
	
	mid = env->GetMethodID(cls, "executeUpdate", "(Ljava/lang/String;)Ljava/lang/String;"); 
	if (mid != 0) {
		// build arg string
		jstring arg = env->NewStringUTF(sql.c_str());
				
		// call method
		jstring result = (jstring) env->CallObjectMethod(obj, mid, arg);	
				 	
		// convert result
		const char* cstr = env->GetStringUTFChars(result, 0);
			
		// copy result to c++ string
		string res = string(cstr);
				
		// cleanup
		env->ReleaseStringUTFChars(result, cstr); 
		env->DeleteLocalRef(result);
		env->DeleteLocalRef(arg);
				
		// return result
		return res;	
	}
	cerr << "Error calling method 'executeQuery'" << endl;
	return false;
}

